/*
* Copyright (c) 2006 by Kirill Kolodyazhniy.
* See the file "license.terms" for information on usage and redistribution.
*/

#ifndef M_MUTEX_H
#define M_MUTEX_H

#ifdef WIN32
#include <windows.h> 
#else
#include <pthread.h>
#endif


namespace Engine
{	
#ifdef WIN32
	/** Class represent mutex wrapper.
	*/
	class Mutex
	{
	public:
		
		/** Constructor.
		*   Simply create mutex object.
		*/
		Mutex()
		{
			m_hMutex=CreateMutex(0,FALSE,0);
		}
		
		/** Destructor.
		*   Wait for mutex, release it and destroy.
		*/
		~Mutex()
		{
			CloseHandle(m_hMutex);
		}
		
		/** Get owner ship.
		*/
		void Lock()const
		{
			WaitForSingleObject(m_hMutex,INFINITE);
		}
		
		/** Release owner ship.
		*/
		void Unlock()const
		{
			ReleaseMutex(m_hMutex);
		}
	private:
		
		/** Copy-constructor not implemented.
		*/
		Mutex( const Mutex & );
		
		/** Copy-assignment operator not implemented.
		*/
		Mutex & operator = ( const Mutex & );
		
		/** Handle to mutex object.
		*/
		HANDLE m_hMutex;
	};
#else
	/** Class represent mutex wrapper.
	*/
	class Mutex
	{
	public:
		
		/** Constructor.
		*   Simply create mutex object.
		*/
		Mutex()
		{
			::pthread_mutex_init(&m_Mutex,0);
		}
		
		/** Destructor.
		*   Wait for mutex, release it and destroy.
		*/
		~Mutex()
		{
			::pthread_mutex_destroy(&m_Mutex);
		}
		
		/** Get owner ship.
		*/
		void Lock()const
		{
			::pthread_mutex_lock(&m_Mutex);
		}
		
		/** Release owner ship.
		*/
		void Unlock()const
		{
			::pthread_mutex_unlock(&m_Mutex);
		}
	private:
		
		/** Copy-constructor not implemented.
		*/
		Mutex( const Mutex & );
		
		/** Copy-assignment operator not implemented.
		*/
		Mutex & operator = ( const Mutex & );
		
		/** Mutex object.
		*/
		
		mutable pthread_mutex_t m_Mutex;
	};
#endif
}

#endif
